﻿using System;
using System.Linq;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.CommonBot;
using Buddy.Swtor;

using WingIt.Dynamics;
namespace WingIt.Routines.Advanced.Sniper
{
    //currently being developed by xsol
    //5/8/2012
    //testing with lvl 35 sniper
    public class Marksmanship
    {
        public static bool IsInCover
        {
            get
            {
                return (BuddyTor.Me.HasBuff("Crouch") || BuddyTor.Me.HasBuff("Cover") || BuddyTor.Me.HasBuff("Unshakable"));
            }
        }

        public const int EnergyMin = 60;

        public const float RangedDistance = 2.8f;
        public const float MeleeDistance = 0.3f;

        public const int HealthShield = 90;
        public const int HealthCritical = 40;

        [Behavior(BehaviorType.Combat)]
        [Class(CharacterClass.Agent, AdvancedClass.Sniper, SkillTreeId.SniperMarksmanship)]
        public static Composite MarksmanshipCombat()
        {
            return new PrioritySelector(
                Movement.StopInRange(RangedDistance),
                Spell.WaitForCast(),

                //***Generel***
                Spell.Cast("Escape ", castWhen => BuddyTor.Me.IsStunned),
                Spell.Cast("Crouch", ret => BuddyTor.Me, ret => BuddyTor.Me.CurrentTarget.InLineOfSight && !IsInCover && BuddyTor.Me.CurrentTarget.Distance <= RangedDistance),
                
                //**Defensive**

                //**Offensive**
                //interupt
                Spell.Cast("Distraction",
                    castWhen =>
                        BuddyTor.Me.CurrentTarget.IsCasting &&
                        BuddyTor.Me.CurrentTarget.Distance >= MeleeDistance),

                //CC
                Spell.Cast("Debilitate",
                    castWhen =>
                        (BuddyTor.Me.CurrentTarget.IsCasting || BuddyTor.Me.HealthPercent <= HealthCritical) &&
                        BuddyTor.Me.CurrentTarget.Distance <= 0.3f),
                Spell.Cast("Flash Bang", castWhen => Helpers.Targets.Count() >= 2),

                // attempt to debuff any target that can be debuffed and are a "real" threat
                Spell.Cast("Diversion", castWhen => (
                    BuddyTor.Me.CurrentTarget.Toughness != CombatToughness.Weak &&
                    BuddyTor.Me.CurrentTarget.Toughness != CombatToughness.Standard &&
                    BuddyTor.Me.CurrentTarget.Toughness != CombatToughness.RaidBoss)),

                //DPS
                // AoE Grenade, High Damage
                Spell.Cast("Fragmentation Grenade", castWhen => BuddyTor.Me.ResourceStat >= EnergyMin),
                // Medium DPS Grenade, place this every time it is available
                Spell.Cast("Explosive Probe", castWhen => IsInCover),
                //idealy we want to cast this every time it is off cd
                Spell.Cast("Followthrough", castWhen => BuddyTor.Me.ResourceStat >= EnergyMin && IsInCover),
                // Only ambush when we have the buff from a snipe crit and we know we will only dip a little below 60 energy (actually regen will prevent the dip below)
                Spell.Cast("Ambush", castWhen =>
                    IsInCover &&
                    BuddyTor.Me.HasBuff("Reactive Shot") &&
                    BuddyTor.Me.ResourceStat >= EnergyMin),
                //buff snipe to ensure a crit
                Spell.Cast("Laze Target", ret => IsInCover && BuddyTor.Me.ResourceStat >= EnergyMin),
                // Medium DPS Shot, this is our main goto dmg and setup skill
                Spell.Cast("Snipe", ret => IsInCover && BuddyTor.Me.ResourceStat >= EnergyMin),
                //finisher, below 30% health
                Spell.Cast("Takedown", castWhen => AbilityManager.CanCast("Takedown", BuddyTor.Me.CurrentTarget)),
                // Low DPS shot, allows time for energy to regen and procs Sniper Volly
                Spell.Cast("Rifle Shot"),


                //enery quick fix
                Spell.Cast("Adrenaline Probe", castWhen => BuddyTor.Me.ResourceStat <= EnergyMin),
                //defense
                Spell.Cast("Shield Probe", castWhen => BuddyTor.Me.HealthPercent <= HealthShield),
                //Spell.Cast("Entrench", castWhen => IsInCover), //need some advance logic here for when to use it
                Movement.MoveTo(ret => BuddyTor.Me.CurrentTarget.Position, RangedDistance)
            );
        }

        [Behavior(BehaviorType.Pull)]
        [Class(CharacterClass.Agent, AdvancedClass.Sniper, SkillTreeId.SniperMarksmanship)]
        public static Composite MarksmanshipPull()
        {
            return MarksmanshipCombat();
        }
    }
}